var http = require('http'),
	fs = require('fs'),
	httpProxy = require('http-proxy'),
	path = require("path"),
	mime = require('./mime');

function isFile(path) {
	if(fs.existsSync( path )){
        return fs.statSync(path).isFile();
    }
}

function getFileExt(file) {
	return file.toString().split(".").pop();
}

/**
 * 向客户端返回静态文件 -- 用流的方式
 * @param  {Array} files 
 * @param  {Stream} res   
 * @return {undefine}       
 */
function resLocalFiles(files,res){

	var stream ;
	
	// recursive function
	function main() {

	    if (!files.length) {
	        res.end();
	        return;
	    }
	    stream = fs.createReadStream(files.shift());
	    stream.pipe(res, {end: false});
	    stream.on("end", function() {
	        main();        
	    });
	}

    res.writeHead(200, "Ok",{'Content-Type': mime[getFileExt(files[0])]});

	if(files.length > 0 ) {
		main();
		console.log('resopn local file :' + files.join(','));
	} else{
		res.writeHead(404, {'Content-Type': 'text/plain'});
		res.end('Not found!');
		console.log('not find');
	}
}


/**
 * 向客户端返回静态文件 -- 用字符串方式
 * @param  {Array} files 
 * @param  {Stream} res   
 * @return {undefine}       
 */
function resLocalFiles2(files,res){

	var filepath,
		ext,
		buf,
        contents = [];

    for (var i = 0; i < files.length; i++) {
    	filepath = files[i];
    	ext = getFileExt(filepath);
        if( isFile( filepath ) ){
            contents.push( fs.readFileSync(filepath) );
        }
    };

	if (contents.length > 0) {
		
		buf = Buffer.concat(contents);

		res.writeHead(200, "Ok",{'Content-Type': mime[ext]});
       	if(/^(?:png|jpg|gif|woff|ttf|eof|svg|otf)$/.test(ext)){
			res.end(buf, 'binary');
       	}else{
	       	res.end(buf.toString());
       	}
       	console.log('resopn local file :' + files.join(','));
	}else{
		res.writeHead(404, {'Content-Type': 'text/plain'});
		res.end('Not found!');
		console.log('not find');
	}
}


function proxyToRemote(url,req,res) {

	var fproxy = httpProxy.createProxyServer();
	fproxy.web(req, res, { target: url });
	console.log('resopn remote file :' + url);
}


function splitPathToFiles(path) {
	
	var qqIdx = path.indexOf('??'),
		files , dirpre;

	if( qqIdx >= 0) {

		dirpre = path.substr(0,qqIdx);
		files = path.substr(qqIdx+2).split(',');

		files.forEach(function(v,j){
			files[j] = dirpre + v;
		});
	}else{
		files = [path];
	}

	return files;
}



// Create an HTTP tunneling proxy
proxy = http.createServer(function (req, res) {

	var url = req.url.toString(), 
		rules = require('./rules'),
		rule , match , ruleType ;

	
	for( var i = rules.length - 1; i >= 0 ; i-- ) {

		rule = rules[i];
		
		match = url.match(rule.pattern);
		if(match) {
			if(toString.call(rule.pattern) === '[object RegExp]') {
				ruleType = 3;
			}else {
				if(!mime[getFileExt(rule.pattern)] && !mime[getFileExt(rule.responder)]) {
					//文件尾缀为空，为目录匹配
					ruleType = 4;
				} else {
					if(rule.responder.indexOf('http') === 0) {
						ruleType = 2;
					}else{	
						ruleType = 1;
					}
				}
			}
		}
	}

	switch(ruleType) {
		case 1:
			//代理单个文件到本地
			resLocalFiles(splitPathToFiles(rule.responder),res);
			break;
		case 2:
			//代理到远程文件
			proxyToRemote(rule.responder,req,res);
			break;
		case 3: 
			//正则表达式
			var match = url.match(rule.pattern),
				path ;

			match.shift();
			path = rule.responder.replace(/\$\d+/g, function(){
				return match.shift()
			});
			
			if(path.indexOf('http') === 0) {
				proxyToRemote(path,req,res);
			}else{
				resLocalFiles(splitPathToFiles(path),res);
			}

			break;
		case 4:
			//目录
			var path = rule.responder + url.substr(url.indexOf(rule.pattern) + rule.pattern.length );

			if(path.indexOf('http') === 0) {
				proxyToRemote(path,req,res);
			}else{
				resLocalFiles(splitPathToFiles(path),res);
			}
			break;
		default:
			proxyToRemote(url,req,res);
	}

	
});

// now that proxy is running
proxy.listen(1338, '127.0.0.1');
console.log('file proxy server is running');


